﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BattleOfColors.Model
{
    /// <summary>
    /// Classe responsável por representar um comportamento definido pelos pesos.
    /// </summary>
    public class Behavior
    {
        public static Behavior AggressiveBehavior()
        {
            Behavior aggressive = new Behavior();

            //Somatório resulta em 100
            aggressive.Group = 2;
            aggressive.Help = 3;
            aggressive.Attack = 5;
            aggressive.Run = 2.5f;

            aggressive.Greedy = 2;
            aggressive.Wait = 2;
            aggressive.Explore = 7;

            aggressive.GiveUp = 20;

            return aggressive;
        }

        /// <summary>
        /// Construtor default geral dos comportamentos.
        /// </summary>
        private Behavior()
        {
            Up = 25;
            Down = 25;
            Left = 25;
            Right = 25;
        }

        /// <summary>
        /// Método para reduzir a tendência de movimento de uma determinada posição
        /// e redistribuir essa quantia igualmente entre os demais. Restrito para reduções
        /// múltiplas de 3. Caso a tendência caía para um valor menor do que 1, a redução
        /// é ignorada.
        /// </summary>
        /// <param name="movement"></param>
        /// <param name="value"></param>
        public void ReduceMovementTendencie(Model.Movement movement, int value)
        {
            if (value % 3 != 0)
            {
                return;
            }

            int increment = (int)((float)value / 3);

            switch (movement)
            {
                case Movement.UP:
                    if (Up - value >= 1)
                    {
                        Up -= value;
                        Down += increment;
                        Left += increment;
                        Right += increment;
                    }
                    break;
                case Movement.DOWN:
                    if (Down - value >= 1)
                    {
                        Up += increment;
                        Down -= value;
                        Left += increment;
                        Right += increment;
                    }
                    break;
                case Movement.LEFT:
                    if (Left - value >= 1)
                    {
                        Up += increment;
                        Down += increment;
                        Left -= value;
                        Right += increment;
                    }
                    break;
                case Movement.RIGHT:
                    if (Right - value >= 1)
                    {
                        Up += increment;
                        Down += increment;
                        Left += increment;
                        Right -= value;
                    }
                    break;
            }
        }

        public void IncreaseMovementTendencie(Model.Movement movement, int value)
        {
            if (value % 3 != 0)
            {
                return;
            }

            int decrement = (int)((float)value / 3);

            switch (movement)
            {
                case Movement.UP:
                    if (Up + value <= 100)
                    {
                        Up += value;
                        Down -= decrement;
                        Left -= decrement;
                        Right -= decrement;
                    }
                    break;
                case Movement.DOWN:
                    if (Down + value <= 100)
                    {
                        Up -= decrement;
                        Down += value;
                        Left -= decrement;
                        Right -= decrement;
                    }
                    break;
                case Movement.LEFT:
                    if (Left + value <= 100)
                    {
                        Up -= decrement;
                        Down -= decrement;
                        Left += value;
                        Right -= decrement;
                    }
                    break;
                case Movement.RIGHT:
                    if (Right + value <= 100)
                    {
                        Up -= decrement;
                        Down -= decrement;
                        Left -= decrement;
                        Right += value;
                    }
                    break;
            }
        }

        #region atributos relacionados ao comportamento geral do soldado
        private float _group;
        /// <summary>
        /// Tendência do soldado a permanecer em grupo
        /// </summary>
        public float Group
        {
            get { return _group; }
            set { _group = value; }
        }

        private float _help;
        /// <summary>
        /// Tendência do soldado de correr a socorro de um aliado
        /// </summary>
        public float Help
        {
            get { return _help; }
            set { _help = value; }
        }

        private float _explore;
        /// <summary>
        /// Tendência do soldado de explorar a região
        /// </summary>
        public float Explore
        {
            get { return _explore; }
            set { _explore = value; }
        }

        private float _attack;
        /// <summary>
        /// Tendência do soldado de atacar um inimigo
        /// </summary>
        public float Attack
        {
            get { return _attack; }
            set { _attack = value; }
        }

        private float _greedy;
        /// <summary>
        /// Tendência do soldado a coletar itens ou dinheiro
        /// </summary>
        public float Greedy
        {
            get { return _greedy; }
            set { _greedy = value; }
        }

        private float _run;
        /// <summary>
        /// Tendência do soldado de fugir
        /// </summary>
        public float Run
        {
            get { return _run; }
            set { _run = value; }
        }

        private float _wait;
        /// <summary>
        /// Tendência do soldado de permanecer sem ação
        /// </summary>
        public float Wait
        {
            get { return _wait; }
            set { _wait = value; }
        }

        private float _giveUp;

        /// <summary>
        /// Atributo da memória que representa o quanto o soldado deve permanecer com a mesma atitude repetida
        /// </summary>
        public float GiveUp
        {
            get { return _giveUp; }
            set { _giveUp = value; }
        }
        #endregion

        #region Atributos relacionados à tendência de se mover para determinada posição
        private int _up;

        public int Up
        {
            get { return _up; }
            set { _up = value; }
        }

        private int _down;

        public int Down
        {
            get { return _down; }
            set { _down = value; }
        }

        private int _left;

        public int Left
        {
            get { return _left; }
            set { _left = value; }
        }

        private int _right;

        public int Right
        {
            get { return _right; }
            set { _right = value; }
        }
        #endregion
    }
}
